<?php


include_once __DIR__ . "/../base.php";
include_once "xml.php";
include_once 'XmlseclibsAdapter.php';
include_once 'http.php';

class huilian extends base
{
    protected $xml;
    protected $head;

    protected $channel_type = "WX";

    protected $appid;
    protected $merchant_id;
    protected $IsvOrgId;
    protected $privateKey;
    protected $publicKey;
    protected $provider_type;

    public $gateUrl = 'https://open.huilianpay.com/pay';


    public function __construct($setting)
    {
        parent::__construct($setting);
        $this->xml = new xml();
        $this->appid = $setting['appid'];  //应用id
        $this->merchant_id = $setting['mchid'];  //商户号
        $this->IsvOrgId = $setting['isv'];  //合作方机构号
        $this->privateKey = $setting['privateKey'];
        $this->publicKey = $setting['publicKey'];
        $this->provider_type = $setting['provider_type'];
    }
    // 提交支付
    public function submitOrder($data)
    {
        $this->head = array(
            'Version' => '1.0.0',
            'Appid' => $this->appid,  //
            'ReqTime' => date('Y-m-d H:i:s.275'), // 2019-04-23 20:32:53.275
            'ReqTimeZone' => 'UTC+8',
            'ReqMsgId' => $this->getRandomString(),
            'InputCharset' => 'UTF-8',
        );
        $data['body'] = $data['OutTradeNo'];
        $this->head['Function'] = 'ant.mybank.bkmerchanttrade.prePay';
        // $data['success_back_page']支付完成页面
        $data += array(
            'IsvOrgId' => $this->IsvOrgId,
            'HlMerchantId' => $this->merchant_id, //测试商户号
            'Currency' => 'CNY',
            'ChannelType' => $this->channel_type,
            'RsaType' => "02",  // 01:机构密钥  02:商户密钥  03:设备密钥  （根据实际情况传）
            'ProviderType' => $this->provider_type,  //09合利宝 (其它有需要可询问客服)
            "NotifyUrl" => $this->callback_url,
            "sucUrl" => $data['success_back_page'],
            "payType" => "AppPayApplet" //小程序支付
        );
        //1todo  SucUrl
        $file_name = $_SERVER['DOCUMENT_ROOT'] . "/../api_resource/logs/" . date('Ymd') . "_pay.log";

        file_put_contents($file_name, date("Y-m-d H:i:s", (time())) . "--------huilian请求报文：---------", FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);
        file_put_contents($file_name, $data, FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);

        $resultXml = $this->submit($data);
        $objectxml = (array)simplexml_load_string($resultXml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $jsonStr = json_encode($objectxml);
        $ret2 = json_decode($jsonStr, true);
        $ret = $ret2['response']['body']['RespInfo'];
        $file_name = $_SERVER['DOCUMENT_ROOT'] . "/../api_resource/logs/" . date('Ymd') . "_pay.log";

        file_put_contents($file_name, date("Y-m-d H:i:s", (time())) . "--------huilian响应报文：---------", FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);
        file_put_contents($file_name, $jsonStr, FILE_APPEND);
        file_put_contents($file_name, "\r\n", FILE_APPEND);

        if ($ret['ResultStatus'] == 'true' || $ret['ResultStatus'] == 'S') {
            // $verifyRes = $this->verify($resultXml);
            $payInfo = $ret2['response']['body']['PayInfo'];
            $payInfo = json_decode($payInfo);
            $payInfo->timestamp = $payInfo->timeStamp;
            return array('status' => 1, 'payInfo' => $payInfo);
            // if ($this->verify($resultXml)) {

            //     $payInfo = $ret2['response']['body']['PayInfo'];
            //     return array('status' => 1, 'url' => $payInfo);
            // } else {
            //     // file_put_contents('20190920.txt', "false", FILE_APPEND);
            // }
        }
        return array('status' => 0, 'msg' => $ret['ResultCode'] . ' | ' . $ret['ResultMsg']);
    }
    public function submit($data)
    {
        $xml = '<document><request><head>' . $this->xml->toXml($this->head) . '</head><body>' . $this->xml->toXml($data) . '</body></request></document>';

        $pass_key = $this->privateKey;
        $pass_key = chunk_split($pass_key, 64, "\n");
        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n$pass_key-----END RSA PRIVATE KEY-----\n";
        $xmlTool = new XmlseclibsAdapter();
        $xmlTool->setPrivateKey($private_key);
        $xmlTool->addTransform(XmlseclibsAdapter::ENVELOPED);
        $xmlDocument = new DOMDocument();
        $xmlDocument->loadXML(trim($xml));
        $xmlTool->sign($xmlDocument);
        $post_data = $xmlDocument->saveXML();



        $http = new Http($this->gateUrl, $post_data);
        $http->setBuild(0);
        $http->setHeader('xml');
        $http->toUrl();
        $resultXml = $http->getResContent();


        // file_put_contents('20190920.txt', "--------响应报文：---------", FILE_APPEND);
        // file_put_contents('20190920.txt', "\r\n", FILE_APPEND);
        // file_put_contents('20190920.txt', $resultXml, FILE_APPEND);
        // file_put_contents('20190920.txt', "\r\n", FILE_APPEND);
        return $resultXml;
    }
    //退款
    public function refund($order_sn, $refund_order_sn, $refund_price, $remark)
    {
        $this->head['Function'] = 'ant.mybank.bkmerchanttrade.refund';
        if (strlen($remark) > 10) {
            $remark = "失败退款";
        }
        $data = array(
            'HlMerchantId' => $this->merchant_id,
            'IsvOrgId' => $this->IsvOrgId,
            'OutTradeNo' => $order_sn,
            'ProviderType' => $this->provider_type,
            'RsaType' => "02",
            'RefundAmount' => $refund_price,
            'OutRefundNo' => $refund_order_sn,
            'RefundReason' => $remark,
            // 'OutRefundNo' => $refund_order_sn,
        );
        $file_name = $_SERVER['DOCUMENT_ROOT'] . "/../api_resource/logs/" . date('Ymd') . "_pay.log";

        // file_put_contents($file_name, "--------huilian退款请求报文：---------", FILE_APPEND);
        // file_put_contents($file_name, "\r\n", FILE_APPEND);
        // file_put_contents($file_name, json_encode($data), FILE_APPEND);
        // file_put_contents($file_name, "\r\n", FILE_APPEND);
        $this->log('退款请求:' . json_encode($data));
        $resultXml = $this->submit($data);
        $objectxml = (array)simplexml_load_string($resultXml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $jsonStr = json_encode($objectxml);

        $file_name = $_SERVER['DOCUMENT_ROOT'] . "/../api_resource/logs/" . date('Ymd') . "_pay.log";
        // $this->log('退款请求:'.$jsonStr);
        // file_put_contents($file_name, "--------huilian退款响应报文：---------", FILE_APPEND);
        // file_put_contents($file_name, "\r\n", FILE_APPEND);
        // file_put_contents($file_name, $jsonStr, FILE_APPEND);
        // file_put_contents($file_name, "\r\n", FILE_APPEND);

        $ret = json_decode($jsonStr, true);

        $this->log($order_sn . '退款返回:' . $jsonStr);
        $ret = $ret['response']['body'];
        $data = [
            "code" => 200,
            "data" => [],
            "msg" => $ret['RespInfo']['ResultMsg'] ?? ''
        ];
        if ($ret['RespInfo']['ResultStatus'] == 'S' && $ret['RespInfo']['ResultCode'] == '000') {
            // if ($this->verify($resultXml)) {
            $data['code'] = 200;
            $data['data'] = [
                'RespInfo' => $ret['RespInfo'],
                'ret' => $ret,
            ];
            // }
        } else {
            $data['code'] = 500;
            // $data['msg'] = "退款申请失败";
        }
        return $data;
    }
    public function notifyOrder()
    {
        $resultXml = file_get_contents('php://input');
        // $this->log('notifyOrder', $resultXml);

        $objectxml = (array)simplexml_load_string($resultXml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $jsonStr = json_encode($objectxml);
        $ret2 = json_decode($jsonStr, true);

        $ret = $ret2['request']['body'];
        $resData = [
            'code' => 200,
            "data" => [],
            "msg" => "",
            "resp" => 'fail'
        ];
        // if ($this->verify($resultXml)) {
        // $this->log('submitOrderResult01', 'ok');
        $resData["code"] = 200;
        $resData["resp"] = "SUCCESS";
        $resData["data"] = [
            "order_sn" => $ret['OutTradeNo'],
            "total_fee" => $ret['TotalAmount'] / 100,

        ];
        // "resp" => ""
        // } else {
        //     $resData["code"] = 500;
        // }
        return $resData;
    }
    public function queryOrder($orderid)
    {
        $this->head['Function'] = 'ant.mybank.bkmerchanttrade.payQuery';
        $data = array(
            'MerchantId' => $this->merchant_id,
            'IsvOrgId' => $this->IsvOrgId,
            'OutTradeNo' => $orderid,
        );

        $resultXml = $this->submit($data);
        // $this->log('orderQueryResult', $resultXml);

        $objectxml = (array)simplexml_load_string($resultXml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $jsonStr = json_encode($objectxml);
        $ret = json_decode($jsonStr, true);



        $ret = $ret['response']['body'];
        if ($ret['TradeStatus'] == 'succ') {
            if ($this->verify($resultXml)) {
                return array(
                    'orderid' => $ret['OrderNo'],
                    'total_fee' => $ret['TotalAmount'],
                );
            }
        }
        return false;
    }
    public function verify($xml)
    {
        $pass_key = $this->publicKey;
        $pass_key = chunk_split($pass_key, 64, "\n");
        $public_key = "-----BEGIN PUBLIC KEY-----\n$pass_key-----END PUBLIC KEY-----\n";
        $xmlTool = new XmlseclibsAdapter();
        $xmlTool->setPublicKey($public_key);
        $xmlTool->addTransform(XmlseclibsAdapter::ENVELOPED);
        $xmlTool->setKeyAlgorithm(XMLSecurityKey::RSA_SHA256);
        $xmlDocument = new DOMDocument();
        $xmlDocument->loadXML(trim($xml));
        return $xmlTool->verify($xmlDocument);
    }
    public function getRandomString()
    {
        // mt_srand((float)microtime() * 10000); //optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        // $hyphen = chr(45); // "-"
        $uuid = substr($charid, 0, 8)
            . substr($charid, 8, 4)
            . substr($charid, 12, 4)
            . substr($charid, 16, 4)
            . substr($charid, 20, 12);
        return $uuid;
    }
}
